package bundle;

import java.util.HashMap;
import java.util.LinkedList;

import application.*;

public class BundleStorage {

	public HashMap<String, BundleList> storage;
	final long MAXTIME = 1000 * 3600 * 36;
	public long size = 0;
	public long storedPackets = 0;
	public long targets = 0;

	public BundleStorage() {
		storage = new HashMap<String, BundleList>();
	}

	public void updateGraph() {
		ApplicationLayer.mainWindow.setBufferSizeLabel(size, targets,
				storedPackets);
	}

	public synchronized BundleList get(String s) {
		BundleList msgs = storage.get(s);
		size -= msgs.size();
		storedPackets -= msgs.list.size();
		targets--;
		storage.remove(s);
		updateGraph();
		return msgs;
	}

	public synchronized void addBundle(String dest, String msg) {
		System.out.println("Storing a message");
		if (!storage.containsKey(dest)) {
			targets++;
			storage.put(dest, new BundleList(msg));
			size += dest.length() + storage.get(dest).size();
		} else {
			storage.get(dest).add(msg);
			size += storage.get(dest).size();
		}
		storedPackets++;
		updateGraph();
	}

	public synchronized void clean() {
		long locSize = 0;
		HashMap<String, BundleList> toRemove = new HashMap<String, BundleList>();
		LinkedList<String> stringToRemove = new LinkedList<String>();
		for (String s : storage.keySet()) {
			boolean superfluous = true;
			for (Long l : storage.get(s).list.keySet()) {
				if (System.currentTimeMillis() > l + MAXTIME) {
					if (!toRemove.containsKey(s)) {
						toRemove.put(s, new BundleList());
					}
					toRemove.get(s).list.put(l, null);
					storedPackets--;
				} else {
					superfluous = false; // A message has been kept, thus we
											// will keep that destination in the
											// table
					locSize += Long.SIZE / 8
							+ storage.get(s).list.get(l).length();
				}
			}
			if (superfluous) {
				stringToRemove.add(s);
				targets--;
			} else {
				locSize += s.length();
			}
		}
		for (String s : toRemove.keySet()) {
			for (Long l : toRemove.get(s).list.keySet()) {
				storage.get(s).remove(l);
			}
		}
		for (String s : stringToRemove) {
			storage.remove(s);
		}
		size = locSize;
		updateGraph();
	}

}